package com.vilen.cms.service;

import com.vilen.basic.model.Pager;
import com.vilen.basic.util.SecurityUtil;
import com.vilen.cms.dao.IGroupDao;
import com.vilen.cms.dao.IRoleDao;
import com.vilen.cms.dao.IUserDao;
import com.vilen.cms.model.CmsException;
import com.vilen.cms.model.Group;
import com.vilen.cms.model.Role;
import com.vilen.cms.model.User;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

/**
 * Created by vilen on 2015/8/26.
 */
@Service("userService")
public class UserService implements  IUserService{
    private IUserDao userDao;
    private IRoleDao roleDao;
    private IGroupDao groupDao;

    public IUserDao getUserDao() {
        return userDao;
    }
    @Inject
    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }

    public IRoleDao getRoleDao() {
        return roleDao;
    }
    @Inject
    public void setRoleDao(IRoleDao roleDao) {
        this.roleDao = roleDao;
    }

    public IGroupDao getGroupDao() {
        return groupDao;
    }
    @Inject
    public void setGroupDao(IGroupDao groupDao) {
        this.groupDao = groupDao;
    }

    private void addUserRole(User user,int rid){
        //1.检查角色对象是否存在，如果不存在，抛出异常
        Role role = roleDao.load(rid);
        if(role == null) {
            throw new CmsException("要添加的用户角色不存在");
        }
        //2.检查用户角色对象是否已经存在 如果存在，就不添加
        userDao.addUserRole(user,role);
    }
    private void addUserGroup(User user,int gid) {
        //1.
        Group group = groupDao.load(gid);
        if(group == null){
            throw new CmsException("要添加的用户组不存在");
        }
        userDao.addUserGroup(user,group);
    }

    @Override
    public void add(User user, Integer[] rids, Integer[] gids) {
        //1判断用户是否存在
        User tu = userDao.loadByUsername(user.getUsername());
        if(tu!=null) {
            throw new CmsException("添加的用户对象已经存在，不能添加");
        }
        user.setCreateDate(new Date());
        try {
            user.setPassword(SecurityUtil.md5(user.getUsername(),user.getPassword()));
        } catch (NoSuchAlgorithmException e) {
            throw new CmsException("密码加密失败:"+e.getMessage());
        }
        userDao.add(user);
        //添加角色对象
        for(Integer rid:rids) {
            this.addUserRole(user, rid);
        }
        //添加用户组对象
        for(Integer gid:gids) {
            this.addUserGroup(user,gid);
        }
    }

    @Override
    public void delete(int id) {
        //TODO 需要进行用户是否有文章的判断

        //1.删除用户关联的角色对象
        userDao.deleteUserRoles(id);
        //2.删除用户管理的组对象
        userDao.deleteUserGroups(id);
        userDao.delete(id);
    }

    @Override
    public void update(User user, Integer[] rids, Integer[] gids) {
        //1.获取用户的已经存在的组id和角色id
        List<Integer> erids = userDao.listUserRoleIds(user.getId());
        List<Integer> egids = userDao.listUserGroupIds(user.getId());
        //2 判断 erids中不存在rids就要添加
        for(Integer rid : rids) {
            if(!erids.contains(rid)){
                //添加
                this.addUserRole(user,rid);
            }
        }
        for(Integer gid: gids) {
            if(!egids.contains(gid)){
                addUserGroup(user,gid);
            }
        }
        // 进行删除
        for(Integer erid : erids) {
            if(!ArrayUtils.contains(rids,erid)){
                userDao.deleteUserRole(user.getId(), erid);
            }
        }
        for (Integer egid : egids) {
            if(!ArrayUtils.contains(gids,egid)){
                userDao.deleteUserGroup(user.getId(),egid);
            }
        }

    }

    @Override
    public void updateStatus(int id) {
        User u = userDao.load(id);
        if(u == null){
            throw new CmsException("修改状态的用户不存在");
        }
        if(u.getStatus()==0) {
            u.setStatus(1);
        }else{
            u.setStatus(0);
        }
        userDao.update(u);
    }

    @Override
    public Pager<User> findUser() {
        return userDao.findUser();
    }

    @Override
    public User load(int id) {
        return userDao.load(id);
    }

    @Override
    public List<Role> listUserRoles(int id) {
        return userDao.listUserRoles(id);
    }

    @Override
    public List<Group> listUserGroups(int id) {
        return userDao.listUserGroups(id);
    }

    @Override
    public List<Integer> listUserRoleIds(int id) {
        return userDao.listUserRoleIds(id);
    }

    @Override
    public List<Integer> listUserGroupIds(int id) {
        return userDao.listUserGroupIds(id);
    }

    @Override
    public List<User> listGroupUsers(int gid) {
        return userDao.listGroupUsers(gid);
    }

    @Override
    public List<User> listRoleUsers(int rid) {
        return userDao.listRoleUsers(rid);
    }

    @Override
    public User login(String username, String password) {
        User user = userDao.loadByUsername(username);
        if (user == null) {
            throw new CmsException("用户名或密码不正确!");
        }
        try {
            if (!SecurityUtil.md5(username,password).equals(user.getPassword())) {
                throw new CmsException("用户名或密码不正确!");
            }
        } catch (NoSuchAlgorithmException e) {
            throw new CmsException("密码加密失败:"+e.getMessage());
        }
        if (user.getStatus() == 0) {
            throw new CmsException("用户已经停用,请与管理员联系!");
        }
        return user;
    }

    @Override
    public void update(User user) {
        userDao.update(user);
    }

    @Override
    public void updatePwd(int uid, String oldPwd, String newPwd) {
        User u = userDao.load(uid);
        try {
            if (!SecurityUtil.md5(u.getUsername(),oldPwd).equals(u.getPassword())) {
                throw new CmsException("原始密码输入不正确!");
            }
        } catch (NoSuchAlgorithmException e) {
            throw new CmsException("密码加密失败:"+e.getMessage());
        }

        try {
            u.setPassword(SecurityUtil.md5(u.getUsername(),newPwd));
        } catch (NoSuchAlgorithmException e) {
            throw new CmsException("密码加密失败:"+e.getMessage());
        }
        userDao.update(u);
    }
}
